package roles

import (
	"context"
	"fmt"
	"time"

	"github.com/google/uuid"
	"github.com/sirupsen/logrus"

	"xagent/internal/actor"
	"xagent/internal/actors"
	proto "xagent/proto/v1"
)

// Chapter 表示小说章节
type Chapter struct {
	ID         string
	Title      string
	Content    string
	WordCount  int
	Characters []string
	Scenes     []Scene
	Status     string
	CreatedAt  time.Time
	UpdatedAt  time.Time
	Version    int
	Metadata   map[string]interface{}
}

// Scene 表示章节场景
type Scene struct {
	ID         string
	Title      string
	Content    string
	Characters []string
	Setting    string
	TimeOfDay  string
	Atmosphere string
	WordCount  int
}

// Writer 表示写作者角色
type Writer struct {
	*actor.BaseActor
	chapters map[string]*Chapter
	logger   *logrus.Logger
}

// NewWriter 创建新的写作者
func NewWriter() *Writer {
	baseActor := actor.NewBaseActor(
		"writer",
		"Writer",
		"负责具体章节的写作",
	)

	w := &Writer{
		BaseActor: baseActor,
		chapters:  make(map[string]*Chapter),
		logger:    logrus.New(),
	}

	// 注册动作
	w.AddAction(&WriteChapterAction{writer: w})
	w.AddAction(&WriteSceneAction{w: w})
	w.AddAction(&ReviseChapterAction{w: w})

	return w
}

// WriteChapterAction represents an action to write a chapter
type WriteChapterAction struct {
	writer *Writer
}

// Name implements the Action interface (deprecated)
func (a *WriteChapterAction) Name() string {
	return "write_chapter"
}

// GetName implements the Action interface
func (a *WriteChapterAction) GetName() string {
	return "write_chapter"
}

// GetDescription implements the Action interface
func (a *WriteChapterAction) GetDescription() string {
	return "Writes a new chapter based on the provided outline"
}

// Prerequisites implements the Action interface (deprecated)
func (a *WriteChapterAction) Prerequisites() []string {
	return []string{"outline"}
}

// GetPrerequisites implements the Action interface
func (a *WriteChapterAction) GetPrerequisites() []string {
	return []string{"outline"}
}

// Validate implements the Action interface
func (a *WriteChapterAction) Validate(input interface{}) error {
	return validateChapterInput(input)
}

// Run implements the Action interface
func (a *WriteChapterAction) Run(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task, ok := input.(*proto.Task)
	if !ok {
		return nil, fmt.Errorf("invalid input type")
	}

	if err := validateChapterInput(task); err != nil {
		return nil, err
	}

	return executeChapterWriting(ctx, task)
}

// Execute method is deprecated, use Run instead
func (a *WriteChapterAction) Execute(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	return a.Run(ctx, input)
}

// NewWriteChapterAction creates a new write chapter action
func NewWriteChapterAction() *WriteChapterAction {
	return &WriteChapterAction{}
}

type WriteSceneAction struct {
	w *Writer
}

func (a *WriteSceneAction) Name() string {
	return "write_scene"
}

func (a *WriteSceneAction) Prerequisites() []string {
	return []string{"write_chapter"}
}

func (a *WriteSceneAction) Run(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task, ok := input.(*proto.Task)
	if !ok {
		return nil, fmt.Errorf("invalid input type")
	}

	chapterID := task.Metadata["chapter_id"]
	chapter, ok := a.w.chapters[chapterID]
	if !ok {
		return nil, fmt.Errorf("chapter not found: %s", chapterID)
	}

	// 思考场景写作
	thought, err := a.w.Think(ctx, fmt.Sprintf("写作场景: %s\n章节背景: %s", task.Description, chapter.Title))
	if err != nil {
		return nil, err
	}

	// 创建新场景
	scene := Scene{
		ID:         uuid.NewString(),
		Title:      task.Name,
		Content:    thought.Content,
		Characters: []string{},
		Setting:    thought.Plan[0],
		TimeOfDay:  thought.Plan[1],
		Atmosphere: thought.Plan[2],
		WordCount:  len(thought.Content),
	}

	chapter.Scenes = append(chapter.Scenes, scene)
	chapter.UpdatedAt = time.Now()
	chapter.WordCount += scene.WordCount

	return &proto.AgentMessage{
		Id:   uuid.NewString(),
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: fmt.Sprintf("场景写作完成: %s\n字数: %d", scene.ID, scene.WordCount),
		},
		Metadata: map[string]string{
			"chapter_id": chapter.ID,
			"scene_id":   scene.ID,
			"word_count": fmt.Sprintf("%d", scene.WordCount),
		},
	}, nil
}

type ReviseChapterAction struct {
	w *Writer
}

func (a *ReviseChapterAction) Name() string {
	return "revise_chapter"
}

func (a *ReviseChapterAction) Prerequisites() []string {
	return []string{"write_chapter"}
}

func (a *ReviseChapterAction) Run(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task, ok := input.(*proto.Task)
	if !ok {
		return nil, fmt.Errorf("invalid input type")
	}

	chapterID := task.Metadata["chapter_id"]
	chapter, ok := a.w.chapters[chapterID]
	if !ok {
		return nil, fmt.Errorf("chapter not found: %s", chapterID)
	}

	// 思考修改建议
	thought, err := a.w.Think(ctx, fmt.Sprintf("修改章节: %s\n当前内容: %s", chapter.Title, chapter.Content))
	if err != nil {
		return nil, err
	}

	// 更新章节
	chapter.Content = thought.Content
	chapter.WordCount = len(thought.Content)
	chapter.UpdatedAt = time.Now()
	chapter.Version++
	chapter.Status = "REVISED"

	return &proto.AgentMessage{
		Id:   uuid.NewString(),
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: fmt.Sprintf("章节修改完成: %s\n新版本: %d\n字数: %d",
				chapter.ID, chapter.Version, chapter.WordCount),
		},
		Metadata: map[string]string{
			"chapter_id": chapter.ID,
			"version":    fmt.Sprintf("%d", chapter.Version),
			"word_count": fmt.Sprintf("%d", chapter.WordCount),
			"status":     chapter.Status,
		},
	}, nil
}

// Helper methods
func (w *Writer) GetChapter(id string) *Chapter {
	return w.chapters[id]
}

func (w *Writer) GetWritingMetrics() map[string]interface{} {
	metrics := make(map[string]interface{})
	totalChapters := len(w.chapters)
	totalWords := 0
	totalScenes := 0
	versions := 0

	for _, chapter := range w.chapters {
		totalWords += chapter.WordCount
		totalScenes += len(chapter.Scenes)
		versions += chapter.Version
	}

	metrics["total_chapters"] = totalChapters
	metrics["total_words"] = totalWords
	metrics["total_scenes"] = totalScenes
	metrics["average_chapter_length"] = float64(totalWords) / float64(totalChapters)
	metrics["average_revisions"] = float64(versions) / float64(totalChapters)

	return metrics
}

// WriterRole represents a writer role that can generate content
type WriterRole struct {
	*actors.BaseRole
	logger *logrus.Entry
}

// NewWriterRole creates a new writer role
func NewWriterRole() *WriterRole {
	role := &WriterRole{
		BaseRole: actors.NewBaseRole(
			"writer",
			"Generates and edits written content",
			[]string{"write", "edit", "review"},
		),
		logger: logrus.WithField("role", "writer"),
	}

	// Add writer-specific actions
	role.AddAction(NewWriteChapterAction())
	role.AddAction(NewEditContentAction())
	role.AddAction(NewReviewContentAction())

	return role
}

// EditContentAction represents an action to edit content
type EditContentAction struct {
	*actors.BaseAction
}

// NewEditContentAction creates a new edit content action
func NewEditContentAction() *EditContentAction {
	return &EditContentAction{
		BaseAction: actors.NewBaseAction(
			"edit_content",
			"Edits and improves content",
			[]string{"content"},
			validateEditInput,
			executeEditing,
		),
	}
}

// ReviewContentAction represents an action to review content
type ReviewContentAction struct {
	*actors.BaseAction
}

// NewReviewContentAction creates a new review content action
func NewReviewContentAction() *ReviewContentAction {
	return &ReviewContentAction{
		BaseAction: actors.NewBaseAction(
			"review_content",
			"Reviews content and provides feedback",
			[]string{"content"},
			validateReviewInput,
			executeReview,
		),
	}
}

// Input validation functions
func validateChapterInput(input interface{}) error {
	chapterInput, ok := input.(*proto.Task)
	if !ok {
		return fmt.Errorf("expected Task input, got %T", input)
	}

	if chapterInput.Description == "" {
		return fmt.Errorf("chapter outline is required")
	}

	return nil
}

func validateEditInput(input interface{}) error {
	editInput, ok := input.(*proto.Task)
	if !ok {
		return fmt.Errorf("expected Task input, got %T", input)
	}

	if editInput.Description == "" {
		return fmt.Errorf("content to edit is required")
	}

	return nil
}

func validateReviewInput(input interface{}) error {
	reviewInput, ok := input.(*proto.Task)
	if !ok {
		return fmt.Errorf("expected Task input, got %T", input)
	}

	if reviewInput.Description == "" {
		return fmt.Errorf("content to review is required")
	}

	return nil
}

// Action execution functions
func executeChapterWriting(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task := input.(*proto.Task)

	// Here we would use the LLM to generate the chapter content
	// For now, we'll return a placeholder response
	return &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: fmt.Sprintf("Generated chapter based on outline: %s", task.Description),
		},
	}, nil
}

func executeEditing(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task := input.(*proto.Task)

	// Here we would use the LLM to edit the content
	return &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: fmt.Sprintf("Edited content: %s", task.Description),
		},
	}, nil
}

func executeReview(ctx context.Context, input interface{}) (*proto.AgentMessage, error) {
	task := input.(*proto.Task)

	// Here we would use the LLM to review the content
	return &proto.AgentMessage{
		Id:   task.Id,
		Type: proto.MessageType_MESSAGE_TYPE_RESPONSE,
		Content: &proto.AgentMessage_Message{
			Message: fmt.Sprintf("Review feedback for: %s", task.Description),
		},
	}, nil
}
